/************************************************************************************
*                                                                                   *
*   MDX2DAE - MDX to COLLADA converter                                              *
*   Copyright (C) 2010  Gunnar Lilleaasen                                           *
*                                                                                   *
*   This program is free software; you can redistribute it and/or                   *
*   modify it under the terms of the GNU General Public License                     *
*   as published by the Free Software Foundation; either version 2                  *
*   of the License, or (at your option) any later version.                          *
*                                                                                   *
*   This program is distributed in the hope that it will be useful,                 *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of                  *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                   *
*   GNU General Public License for more details.                                    *
*                                                                                   *
*   You should have received a copy of the GNU General Public License               *
*   along with this program; if not, write to the Free Software                     *
*   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. *
*                                                                                   *
************************************************************************************/
#include "COLLADA.h"
#include <sstream>
#include <iomanip>

// Output COLLADA document
extern FCDocument* g_doc;

void CreateGeometry(MDX2_Geoset* geoset, uint16_t* triangles, uint16_t* vertexLookup, MDX2_Vertex* vertexList)
{
    FCDGeometry* geometry = g_doc->GetGeometryLibrary()->AddEntity();
    
    std::stringstream ss;
    ss << "geo" << std::setfill('0') << std::setw(2) << g_doc->GetGeometryLibrary()->GetEntityCount();

    geometry->SetDaeId(ss.str().c_str());
    ss.str("");

    FCDGeometryMesh* mesh = geometry->CreateMesh();

    // Time to parse the vertices, starting with their position
    FCDGeometrySource* source = mesh->AddSource(FUDaeGeometryInput::POSITION);    

    ss << "geo" << std::setfill('0') << std::setw(2) << g_doc->GetGeometryLibrary()->GetEntityCount() << "_Pos";

    source->SetDaeId(ss.str().c_str());
    ss.str("");

    FloatList fList(geoset->numVert*3);

    for(unsigned int fcnt = 0, vind = geoset->indVert, end = (geoset->indVert + geoset->numVert); vind != end; vind++)
    {
        fList[fcnt++] = vertexList[vertexLookup[vind]].Position.x;
        fList[fcnt++] = vertexList[vertexLookup[vind]].Position.y;
        fList[fcnt++] = vertexList[vertexLookup[vind]].Position.z;
    }

    source->SetData(fList, 3, 0, fList.size());

    // POSITION should be vertex source, so we add that here
    mesh->AddVertexSource(source);

    // Next up are the vertex normals
    source = mesh->AddSource(FUDaeGeometryInput::NORMAL);

    ss << "geo" << std::setfill('0') << std::setw(2) << g_doc->GetGeometryLibrary()->GetEntityCount() << "_Norm";

    source->SetDaeId(ss.str().c_str());
    ss.str("");

    for(unsigned int fcnt = 0, vind = geoset->indVert, end = (geoset->indVert + geoset->numVert); vind != end; vind++)
    {
        fList[fcnt++] = vertexList[vertexLookup[vind]].Normal.x;
        fList[fcnt++] = vertexList[vertexLookup[vind]].Normal.y;
        fList[fcnt++] = vertexList[vertexLookup[vind]].Normal.z;
    }

    source->SetData(fList, 3, 0, fList.size());

    // Here are the texture coords    
    source = mesh->AddSource(FUDaeGeometryInput::TEXCOORD);

    ss << "geo" << std::setfill('0') << std::setw(2) << g_doc->GetGeometryLibrary()->GetEntityCount() << "_TexCoord";

    source->SetDaeId(ss.str().c_str());
    ss.str("");

    fList.resize(geoset->numVert*2);

    for(unsigned int fcnt = 0, vind = geoset->indVert, end = (geoset->indVert + geoset->numVert); vind != end; vind++)
    {
        fList[fcnt++] = vertexList[vertexLookup[vind]].TextureCoords.u;
        fList[fcnt++] = vertexList[vertexLookup[vind]].TextureCoords.v;
    }

    source->SetData(fList, 2, 0, fList.size());

    // Time for the triangles, and then we're done
    FCDGeometryPolygons* tris = mesh->AddPolygons();
    tris->SetPrimitiveType(FCDGeometryPolygons::POLYGONS);

    tris->AddInput(mesh->GetSource(1), 0);

    UInt32List uiList(geoset->numFaces);

    for(unsigned int icnt = 0, find = geoset->indFaces, end = (geoset->indFaces + geoset->numFaces); find != end; find++, icnt++)
    {
        uiList[icnt] = triangles[find] - geoset->indVert;
    }

    tris->GetInput(0)->AddIndices(uiList);
    tris->GetInput(1)->AddIndices(uiList);

    for(auto i = 0U; i < uiList.size(); i += 3)
    {
        tris->AddFace(3);
    }
}